<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import { ElMessage } from 'element-plus';
import { uploadToExternalService } from '../utils/upload';
import {
  Microphone,
  VideoPlay,
  VideoPause,
  Delete,
  Upload
} from '@element-plus/icons-vue';

const props = defineProps({
  maxDuration: {
    type: Number,
    default: 60 // 最长录音时间，单位秒
  }
});

const emits = defineEmits(['upload-success', 'upload-error', 'remove']);

const isRecording = ref(false);
const isPaused = ref(false);
const audioURL = ref('');
const recordingTime = ref(0);
const timerInterval = ref(null);
const mediaRecorder = ref(null);
const audioChunks = ref([]);
const loading = ref(false);
const audioBlob = ref(null);

// 格式化时间，显示为 MM:SS 格式
const formattedTime = () => {
  const minutes = Math.floor(recordingTime.value / 60);
  const seconds = recordingTime.value % 60;
  return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
};

// 开始录音
const startRecording = async () => {
  try {
    // 请求麦克风权限
    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
    
    // 重置状态
    audioChunks.value = [];
    recordingTime.value = 0;
    
    // 创建 MediaRecorder 实例
    mediaRecorder.value = new MediaRecorder(stream);
    
    // 接收音频数据
    mediaRecorder.value.ondataavailable = (event) => {
      if (event.data.size > 0) {
        audioChunks.value.push(event.data);
      }
    };
    
    // 停止录音后处理音频数据
    mediaRecorder.value.onstop = () => {
      // 合并音频片段
      const audioData = new Blob(audioChunks.value, { type: 'audio/wav' });
      
      // 创建音频URL用于预览
      if (audioURL.value) {
        URL.revokeObjectURL(audioURL.value);
      }
      audioURL.value = URL.createObjectURL(audioData);
      audioBlob.value = audioData;
      
      // 关闭所有音轨
      stream.getTracks().forEach(track => track.stop());
    };
    
    // 开始录音
    mediaRecorder.value.start(100); // 每100ms收集一次数据
    isRecording.value = true;
    isPaused.value = false;
    
    // 更新计时器
    timerInterval.value = setInterval(() => {
      if (!isPaused.value) {
        recordingTime.value++;
        
        // 检查是否达到最大录音时间
        if (recordingTime.value >= props.maxDuration) {
          stopRecording();
        }
      }
    }, 1000);
    
    ElMessage.success('开始录音');
  } catch (error) {
    console.error('无法访问麦克风:', error);
    ElMessage.error('无法访问麦克风，请检查浏览器权限设置');
  }
};

// 暂停录音
const pauseRecording = () => {
  if (!mediaRecorder.value || mediaRecorder.value.state !== 'recording') return;
  
  mediaRecorder.value.pause();
  isPaused.value = true;
  ElMessage.info('录音已暂停');
};

// 继续录音
const resumeRecording = () => {
  if (!mediaRecorder.value || mediaRecorder.value.state !== 'paused') return;
  
  mediaRecorder.value.resume();
  isPaused.value = false;
  ElMessage.info('录音已继续');
};

// 停止录音
const stopRecording = () => {
  if (!mediaRecorder.value || mediaRecorder.value.state === 'inactive') return;
  
  // 停止录音和计时器
  mediaRecorder.value.stop();
  clearInterval(timerInterval.value);
  isRecording.value = false;
  isPaused.value = false;
  
  ElMessage.success('录音已完成');
};

// 重置录音
const resetRecording = () => {
  if (isRecording.value) {
    stopRecording();
  }
  
  if (audioURL.value) {
    URL.revokeObjectURL(audioURL.value);
    audioURL.value = '';
  }
  
  audioBlob.value = null;
  recordingTime.value = 0;
  audioChunks.value = [];
  emits('remove');
};

// 上传录音
const uploadRecording = async () => {
  if (!audioBlob.value) {
    ElMessage.warning('没有可上传的录音');
    return;
  }
  
  try {
    loading.value = true;
    
    // 创建一个文件对象
    const audioFile = new File([audioBlob.value], `audio_${Date.now()}.wav`, {
      type: 'audio/wav'
    });
    
    // 使用外部服务上传
    const result = await uploadToExternalService(audioFile);
    
    if (result.success) {
      ElMessage.success('音频上传成功');
      emits('upload-success', {
        fileUrl: result.fileUrl,
        fileName: result.fileName,
        fileType: 'audio',
        localUrl: audioURL.value
      });
    } else {
      ElMessage.error(result.error || '上传失败');
      emits('upload-error', result.error);
    }
  } catch (error) {
    console.error('上传出错:', error);
    ElMessage.error('音频上传出错');
    emits('upload-error', error.message || '上传出错');
  } finally {
    loading.value = false;
  }
};

// 组件销毁时清理资源
onUnmounted(() => {
  clearInterval(timerInterval.value);
  
  if (audioURL.value) {
    URL.revokeObjectURL(audioURL.value);
  }
  
  if (mediaRecorder.value && mediaRecorder.value.state !== 'inactive') {
    mediaRecorder.value.stop();
  }
});
</script>

<template>
  <div class="audio-recorder">
    <!-- 录音未开始 -->
    <div v-if="!isRecording && !audioURL" class="recorder-empty">
      <el-button type="primary" @click="startRecording" round>
        <el-icon><Microphone /></el-icon>
        开始录音
      </el-button>
    </div>
    
    <!-- 录音中 -->
    <div v-if="isRecording" class="recorder-active">
      <div class="recording-indicator">
        <span class="recording-dot"></span>
        正在录音 {{ formattedTime() }}
      </div>
      
      <div class="recording-controls">
        <el-button 
          v-if="!isPaused" 
          type="warning" 
          @click="pauseRecording" 
          circle
        >
          <el-icon><VideoPause /></el-icon>
        </el-button>
        
        <el-button 
          v-else 
          type="success" 
          @click="resumeRecording" 
          circle
        >
          <el-icon><VideoPlay /></el-icon>
        </el-button>
        
        <el-button 
          type="danger" 
          @click="stopRecording" 
          circle
        >
          <el-icon><Delete /></el-icon>
        </el-button>
      </div>
    </div>
    
    <!-- 录音完成 -->
    <div v-if="audioURL" class="recorder-preview">
      <audio 
        controls 
        :src="audioURL" 
        class="audio-player"
      ></audio>
      
      <div class="preview-controls">
        <el-button 
          type="danger" 
          circle 
          size="small" 
          @click="resetRecording"
        >
          <el-icon><Delete /></el-icon>
        </el-button>
        
        <el-button 
          type="primary" 
          circle 
          size="small" 
          @click="uploadRecording"
          :loading="loading"
        >
          <el-icon v-if="!loading"><Upload /></el-icon>
        </el-button>
      </div>
    </div>
    
    <!-- 加载状态 -->
    <div v-if="loading" class="uploader-loading">
      <el-icon class="is-loading"><Upload /></el-icon>
      <span>上传中...</span>
    </div>
  </div>
</template>

<style scoped>
.audio-recorder {
  width: 100%;
  position: relative;
}

.recorder-empty {
  display: flex;
  justify-content: center;
  padding: 20px;
}

.recorder-active {
  border: 2px solid #f56c6c;
  border-radius: 12px;
  padding: 15px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  background-color: rgba(245, 108, 108, 0.05);
}

.recording-indicator {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #f56c6c;
  font-weight: 500;
}

.recording-dot {
  width: 12px;
  height: 12px;
  background-color: #f56c6c;
  border-radius: 50%;
  display: inline-block;
  animation: blink 1s infinite;
}

@keyframes blink {
  0% { opacity: 1; }
  50% { opacity: 0.3; }
  100% { opacity: 1; }
}

.recording-controls {
  display: flex;
  gap: 16px;
  margin-top: 10px;
}

.recorder-preview {
  border: 2px solid #409EFF;
  border-radius: 12px;
  padding: 15px;
  position: relative;
}

.audio-player {
  width: 100%;
  margin-bottom: 10px;
}

.preview-controls {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.uploader-loading {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(255, 255, 255, 0.7);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 20;
  backdrop-filter: blur(3px);
  border-radius: 12px;
}

.uploader-loading .el-icon {
  font-size: 32px;
  color: #409EFF;
  margin-bottom: 8px;
}
</style> 